/*
 *  dotback: A program to ease the backup and restore of dotfiles
 *  Copyright (C) 2008  Sol Jerome
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "commands.h"
#include "dotback.h"

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

const char dotback_usage_string[] = "dotback [--help] COMMAND [ARGS]";
const char dotback_more_info_string[] =
	"See 'dotback help COMMAND' for information on a specific command.";


/**
 * @struct cmd_struct
 *
 * Structure containing the command and options to pass to that command.
 */
struct cmd_struct {
	const char *cmd;
	int (*fn)(int, const char **, const char *);
	int option;
};

void list_cmds_help(void)
{
	int i, longest = 0;

	for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
		if (longest < strlen(common_cmds[i].name))
			longest = strlen(common_cmds[i].name);
	}

	puts("Available dotback commands are:");
	for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
		printf("   %s   ", common_cmds[i].name);
		mput_char(' ', longest - strlen(common_cmds[i].name));
		puts(common_cmds[i].help);
	}
}

int prefixcmp(const char *str, const char *prefix)
{
	for (; ; str++, prefix++)
		if (!*prefix)
			return 0;
		else if (*str != *prefix)
			return (unsigned char)*prefix - (unsigned char)*str;
}

/**
 * handle_options - handle option parsing for dotback commands
 * @argv: argument vector
 * @argc: number of arguments
 *
 * Use this to parse out all the arguments given to dotback on the
 * command line. It returns the number of arguments handled.
 */
static int handle_options(const char*** argv, int* argc)
{
	int handled = 0;

	while (*argc > 0) {
		const char *cmd = (*argv)[0];
		if (cmd[0] != '-')
			break;
		/*
		 * For legacy reasons, the "version" and "help"
		 * commands can be written with "--" prepended
		 * to make them look like flags.
		 */
		if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version"))
			break;

		(*argv)++;
		(*argc)--;
		handled++;
	}
	return handled;
}

int main(int argc, const char **argv)
{
	const char *cmd = argv[0] && *argv[0] ? argv[0] : "dotback help";

	cmd += 8;
	argv[0] = cmd;

	/* Look for flags */
	argv++;
	argc--;
	handle_options(&argv, &argc);
	if (argc > 0) {
		if (prefixcmp(argv[0], "--") == 0)
			argv[0] += 2;
	} else {
		/* The user didn't specify a command; give them help */
		printf("usage: %s\n\n", dotback_usage_string);
		list_cmds_help();
		printf("\n%s\n", dotback_more_info_string);
		exit(EXIT_FAILURE);
	}
	cmd = argv[0];

	return 0;
}
